package com.hxz.graduationdesign.service.impl;

import com.hxz.graduationdesign.base.response.JsonResult;
import com.hxz.graduationdesign.mapper.CommentMapper;
import com.hxz.graduationdesign.pojo.dto.CommentDto;
import com.hxz.graduationdesign.pojo.entity.Comment;
import com.hxz.graduationdesign.pojo.entity.ReplyComment;
import com.hxz.graduationdesign.pojo.vo.CommentVo;
import com.hxz.graduationdesign.pojo.vo.GenderVo;
import com.hxz.graduationdesign.pojo.vo.LevelVo;
import com.hxz.graduationdesign.pojo.vo.ReplyCommentVo;
import com.hxz.graduationdesign.service.ICommentService;
import com.hxz.graduationdesign.util.ChineseSegmenter;
import com.hxz.graduationdesign.util.SentimentAnalyzer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.*;

import static com.hxz.graduationdesign.util.BilibiliCommentCrawler.getVideoComments;
import static com.hxz.graduationdesign.util.FormattingTool.getChineseSegmenter;
import static com.hxz.graduationdesign.util.FormattingTool.getSentimentAnalyzer;

@Service
@Slf4j
public class CommentService implements ICommentService {

    @Autowired
    private CommentMapper commentMapper;

    public Map<String,Object> queryComment(String bv){

        Map<String,Object> map = new HashMap<>();
        List<ReplyCommentVo> replyCommentVoList = new ArrayList<>();

        try {
            List<CommentVo> commentVos = commentMapper.selectAllComment(bv);
            if (commentVos.isEmpty()){
                List<CommentDto> videoComments = getVideoComments(bv, 500, 500);
                if (videoComments.isEmpty()){
                    return new HashMap<>();
                }

                List<Comment> comments = new ArrayList<>();
                for (CommentDto dto : videoComments) {
                    Comment comment = new Comment();
                    // 复制共有字段
                    BeanUtils.copyProperties(dto, comment);
                    // 手动设置 bv（假设从其他地方获取，如视频参数）
                    comment.setBv("视频BV号");
                    comments.add(comment);
                }
                for(Comment comment:comments){
                    comment.setBv(bv);
//                    System.out.println(comment);
                }
                //将一级评论存入数据库
                int i =addComment(comments);

                if(i>0){


                    map.put("comment",commentMapper.selectAllComment(bv));

                    for(CommentDto commentDto:videoComments){
                        List<ReplyCommentVo> replyCommentVos = queryReplyComment(commentDto, bv);
//                        System.out.println(replyCommentVos);

                        if(!replyCommentVos.isEmpty()){
                            replyCommentVoList.addAll(replyCommentVos);
                        }

                    }

                }else {
                    return null;
                }
                map.put("replyComment",replyCommentVoList);
                return map;

            }else {

                map.put("comment",commentVos);
                for(CommentVo commentVo:commentVos){
                    List<ReplyCommentVo> replyCommentVos = queryReplyCommentOnly(commentVo.getId(),bv);
                    replyCommentVoList.addAll(replyCommentVos);
                }

                map.put("replyComment",replyCommentVoList);

                return map;
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }
//    commentDto.getReplies()

    public int addComment(List<Comment> comments){
        return commentMapper.insertComments(comments);
    }

    public List<ReplyCommentVo> queryReplyComment(CommentDto commentDto,String bv){

        List<ReplyCommentVo> replyCommentVos = commentMapper.selectAllReplyComment(bv, commentDto.getId());

        if(replyCommentVos.isEmpty()){

            List<ReplyComment> replies = commentDto.getReplies();

            for(ReplyComment replyComment:replies){
                replyComment.setRid(commentDto.getId());
                replyComment.setBv(bv);
            }

            if(replies.isEmpty()){
                return new ArrayList<>();
            }else {
                int i = commentMapper.insertReplyComments(replies);

                if (i>0){
                    return commentMapper.selectAllReplyComment(bv, commentDto.getId());
                }else {
                    return null;
                }

            }

        }else {
            return replyCommentVos;
        }

    }

    public List<ReplyCommentVo> queryReplyCommentOnly(String rid,String bv){
        return commentMapper.selectAllReplyComment(bv, rid);
    }

    @Override
    public List<GenderVo> queryGender(String bv) {

        List<GenderVo> genderVos = commentMapper.selectGender(bv);
        List<GenderVo> genderVos1 = commentMapper.selectRelyGender(bv);

        for (GenderVo genderVo : genderVos) {
            for (GenderVo vo : genderVos1) {
                if (genderVo.getGender().equals(vo.getGender())){
                    genderVo.setNum(genderVo.getNum()+ vo.getNum());
                }
            }
        }

        return genderVos;
    }

    @Override
    public List<LevelVo> queryLevel(String bv) {

        List<LevelVo> levelVos = commentMapper.selectLevel(bv);
        List<LevelVo> levelVos1 = commentMapper.selectReplyLevel(bv);

        for (LevelVo levelVo : levelVos) {
            for (LevelVo vo : levelVos1) {
                if(levelVo.getLevel()== vo.getLevel()){
                    levelVo.setNum(levelVo.getNum()+vo.getNum());
                }
            }
        }

        return levelVos;

    }

    @Override
    public Map<String, Object> updateComment(String bv) {

        commentMapper.deleteByBv(bv);
        commentMapper.deleteReplyByBv(bv);

        return queryComment(bv);

    }

    public Map<String,Integer> emo(String bv){
        Map<String, Object> stringObjectMap = queryComment(bv);
        SentimentAnalyzer sentimentAnalyzer = getSentimentAnalyzer();
        List<CommentVo> comment = (List<CommentVo>) stringObjectMap.get("comment");
        List<ReplyCommentVo> replyComment = (List<ReplyCommentVo>) stringObjectMap.get("replyComment");


        List<String> allContents = new ArrayList<>();

        for (CommentVo commentVo : comment) {
            allContents.add(commentVo.getContent());
        }
        for (ReplyCommentVo replyCommentVo : replyComment) {
            allContents.add(replyCommentVo.getContent());
        }
        Map<String,Integer> emo = new HashMap<>();
        emo.put("中立",0);
        emo.put("消极",0);
        emo.put("积极",0);
        for (String content : allContents) {
            String analyze = sentimentAnalyzer.analyze(content);
            if (analyze.equals("中立")){
                emo.compute("中立", (k, v) -> v + 1);
            } else if (analyze.equals("积极")) {
                emo.compute("积极", (k, v) -> v + 1);
            }else if (analyze.equals("消极")){
                emo.compute("消极", (k, v) -> v + 1);
            }
        }
        return emo;
    }

    @Override
    public Map<String, Integer> segmenter(String bv) {
        Map<String, Object> stringObjectMap = queryComment(bv);
        try {
            List<CommentVo> comment = (List<CommentVo>) stringObjectMap.get("comment");
            List<ReplyCommentVo> replyComment = (List<ReplyCommentVo>) stringObjectMap.get("replyComment");
            ChineseSegmenter chineseSegmenter = getChineseSegmenter();

            List<String> allContents = new ArrayList<>();

            for (CommentVo commentVo : comment) {
                allContents.add(commentVo.getContent());
            }
            for (ReplyCommentVo replyCommentVo : replyComment) {
                allContents.add(replyCommentVo.getContent());
            }

            Map<String, Integer> mergedResult = chineseSegmenter.batchSegment(allContents);
            Map<String, Integer> topResult = new LinkedHashMap<>();
            int count = 0;
            for (Map.Entry<String, Integer> entry : mergedResult.entrySet()) {
                if (count >= 70) {
                    break;
                }
                topResult.put(entry.getKey(), entry.getValue());
                count++;
            }

            return topResult;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}
